#include "func.h"
#include "user_login.h"
#include "cmdHandler.h"

//获取盐值
void generate_salt(char *salt, int length)
{
    const char charset[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    srand(time(NULL));
    salt[0]='$';
    salt[1]='6';
    salt[2]='$';
    salt[19]='$';
    for(int i=3;i<19;++i)
    {
        salt[i]=charset[rand()%(sizeof(charset)-1)];

    }
}



int user_login(const int netfd,user_t *puser,MYSQL *mysql){
    //查询用户是否存在
    char sql[1024] = {0};
    sprintf(sql, "select * from user_info where user = \'%s\';", puser->name);

    train_t train;
    //查询失败
    int qret = mysql_query(mysql, sql);
    if(qret != 0) {
        fprintf(stderr, "mysql_real_query: %s\n", mysql_error(mysql));
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return -1;
    }
    //获取查询结果
    MYSQL_RES* res = mysql_use_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(res);
    //用户名不正确
    if(row == NULL){
        fprintf(stderr, "mysql_fetch_row:%s\n", mysql_error(mysql));
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return 1;
    }

    char * salt = row[2];
    char* cryptPasswd = row[3];
    char * makePasswd = crypt(puser->passwd, salt);
    mysql_free_result(res);
    bzero(&train,sizeof(train_t));
    if(strcmp(cryptPasswd, makePasswd) == 0){
        printf("验证通过！\n");
        memcpy(train.data, RET_SUCCESS, strlen(RET_SUCCESS));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return 0;
    }else {
        printf("密码错误！\n");
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return -1;
    }
}


int user_register(const int netfd,user_t *puser,MYSQL *mysql){

    //查询是否存在同名用户
    char sql[1024] = {0};
    sprintf(sql, "select * from user_info where user = \'%s\';", puser->name);
    int qret = mysql_query(mysql, sql);

    train_t train;
    //查询失败
    if(qret != 0){
        fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return -1;
    }

    //获取查询结果
    MYSQL_RES* res = mysql_store_result(mysql);

    //存在相同用户名
    if(mysql_fetch_row(res) != NULL){
        mysql_free_result(res);
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return -2;
    }
    mysql_free_result(res);

    bzero(&train,sizeof(train));
    //发送是否确认
    char buf[256] = "Are you sure?(y/n)";
    bzero(&train,sizeof(train_t));
    train.length = sizeof(buf);
    memcpy(train.data, buf, sizeof(buf));
    send_msg(netfd,&train);
    //接收确认信息
    bzero(&train, sizeof(train_t));
    int ret = recv_msg(netfd, &train);
    if(ret == 0) {
        close(netfd);
        pthread_exit(NULL);
    }
    printf("ret = %s\n",train.data);
    if(strcmp(train.data,"y") == 0){
        char retsalt[21] = {0};
        generate_salt(retsalt, 21);
        //插入新用户
        bzero(sql, sizeof(sql));
        char *cryptPwd = crypt(puser->passwd, retsalt);
        snprintf(sql, sizeof(sql), "insert into user_info (user, salt, password, tomb) values(\'%s\', \'%s\', \'%s\', \'%d\');", puser->name, retsalt, cryptPwd, 0);
        qret = mysql_query(mysql, sql);
        if(qret != 0){
            fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
            return -1;
        }
        bzero(sql,sizeof(sql));
        snprintf(sql, sizeof(sql), "insert into file_info (filename,filepath,user,pre_id,type,tomb) values ('/','/',\'%s\',-1,1,0);",puser->name);
        qret = mysql_query(mysql, sql); 
        if(qret != 0){
            fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
            return -1;
        }
    }
    else{
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return -1;
    }

    /* train_t train; */
    bzero(&train,sizeof(train_t));
    memcpy(train.data, RET_SUCCESS, strlen(RET_SUCCESS));
    train.length=strlen(train.data);
    send_msg(netfd, &train);

    return 0;
}

int user_logoff(const int netfd,user_t *puser,MYSQL *mysql){
    //查询用户是否存在
    char sql[1024] = {0};
    sprintf(sql, "select * from user_info where user = \'%s\';", puser->name);

    //查询失败
    int qret = mysql_query(mysql, sql);
    if(qret != 0) {
        fprintf(stderr, "mysql_real_query: %s\n", mysql_error(mysql));
        return -1;
    }
    //获取查询结果
    MYSQL_RES* res = mysql_use_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(res);
    //用户名不正确
    if(row == NULL){
        fprintf(stderr, "mysql_fetch_row:%s\n", mysql_error(mysql));
        train_t train;
        bzero(&train,sizeof(train_t));
        memcpy(train.data, RET_FAIL, strlen(RET_FAIL));
        train.length=strlen(train.data);
        send_msg(netfd, &train);
        return 1;
    }
    char * salt = row[2];
    char* cryptPasswd = row[3];
    char * makePasswd = crypt(puser->passwd, salt);
    mysql_free_result(res);
    train_t train;
    bzero(&train,sizeof(train_t));
    if(strcmp(cryptPasswd, makePasswd) == 0){

        //发送是否确认
        char buf[256] = "Are you sure?(y/n)";
        bzero(&train,sizeof(train_t));
        train.length = sizeof(buf);
        memcpy(train.data, buf, sizeof(buf));
        send_msg(netfd,&train);
        //接收确认信息
        bzero(&train, sizeof(train_t));
        int ret = recv_msg(netfd, &train);
        if(ret == 0) {
            close(netfd);
            pthread_exit(NULL);
        }
        if(strcmp(train.data,"y") == 0){

            char sql[1024] = {0};
            sprintf(sql, "update user_info set user = concat(user,UNIX_TIMESTAMP()),tomb = 1 where user = \'%s\';", puser->name);
            int qret = mysql_query(mysql, sql);
            if(qret != 0){
                fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
                return -1;
            }
            sprintf(sql, "update file_info set user = concat(user,UNIX_TIMESTAMP()),tomb = 1 where user = \'%s\';", puser->name);
            qret = mysql_query(mysql, sql);
            if(qret != 0){
                fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
                return -1;
            }
            memcpy(train.data, RET_SUCCESS, strlen(RET_SUCCESS));
            train.length=strlen(train.data);
            send_msg(netfd, &train);
        }
    }



    return 0;
}

int hand_login(const int netfd, train_t *ptrain, MYSQL *mysql, user_t *puser, int *flag) {
    cmd_t cmdInfo;
    bzero(&cmdInfo, sizeof(cmd_t)); 
    bzero(puser, sizeof(user_t));
    memcpy(&cmdInfo, ptrain->data, ptrain->length);
    if(strcmp(cmdInfo.cmd, LOGIN) == 0) {
        memcpy(puser, cmdInfo.args, sizeof(user_t));
        printf("username = %s, passwd = %s\n", puser->name, puser->passwd);
        int ret = user_login(netfd, puser, mysql);
        if(!ret) {
            *flag = 1;
        }
    } else if(strcmp(cmdInfo.cmd, REGISTER) == 0) {
        memcpy(puser, cmdInfo.args, sizeof(user_t));
        user_register(netfd, puser, mysql);
    } else if(strcmp(cmdInfo.cmd, LOGOFF) == 0) {
        memcpy(puser, cmdInfo.args, sizeof(user_t));
        user_logoff(netfd, puser, mysql);
    }

    return 0;
}

